package DFA

import "strconv"

type NFA interface {
	In() *node
	Out() *node
}

type DFA struct {
	states  []*state
	begin   *state
	end     []*state
	charSet []byte
}

type field struct {
	in  *node
	out *node
}

func (f field) In() *node {
	return f.in
}
func (f field) Out() *node {
	return f.out
}

type node struct {
	name    string
	edges   map[byte]*node //通过字符可达的节点
	any     []*node        //无条件到达的节点
	isFinal bool
}

// createOrNode 创建 | 对应节点
func createOrNode(a, b NFA, Id *int) NFA {
	var start = new(node)
	start.name = strconv.Itoa(*Id)
	*Id++
	start.any = append(start.any, a.In())
	start.any = append(start.any, b.In())
	var end = new(node)
	end.name = strconv.Itoa(*Id)
	*Id++
	start.edges = make(map[byte]*node)
	end.edges = make(map[byte]*node)
	a.Out().any = append(a.In().any, end)
	b.Out().any = append(b.Out().any, end)
	return field{start, end}
}

// 创建 单个单词节点
func createSingleNode(c byte, Id *int) NFA {
	var start = node{}

	start.name = strconv.Itoa(*Id)
	*Id++
	var end = node{}

	end.name = strconv.Itoa(*Id)
	*Id++
	start.edges = make(map[byte]*node)
	end.edges = make(map[byte]*node)
	start.edges[c] = &end
	return field{&start, &end}
}

// createMulNode 创建 * 节点
func createMulNode(a NFA, Id *int) NFA {
	var start = new(node)

	start.name = strconv.Itoa(*Id)
	*Id++
	start.any = append(start.any, a.In())
	var end = new(node)

	end.name = strconv.Itoa(*Id)
	*Id++
	start.edges = make(map[byte]*node)
	end.edges = make(map[byte]*node)
	a.Out().any = append(a.In().any, end)
	a.Out().any = append(a.Out().any, a.In())
	start.any = append(start.any, end)
	return field{start, end}
}

// createAndNode 创建 ^ 节点
func createAndNode(a, b NFA, Id *int) NFA {
	var start = new(node)
	start.name = strconv.Itoa(*Id)
	*Id++
	var end = new(node)
	end.name = strconv.Itoa(*Id)
	*Id++
	start.edges = make(map[byte]*node)
	end.edges = make(map[byte]*node)
	start.any = append(start.any, a.In())
	a.Out().any = append(a.Out().any, b.In())
	b.Out().any = append(b.Out().any, end)
	return field{start, end}
}
